package com.beerandjesus.sportofkings.handicapper.profile.resolver;

import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Horse;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.HorseRace;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.PastPerformance;
import com.beerandjesus.sportofkings.handicapper.model.brisnet.singlefile.Race;
import com.beerandjesus.sportofkings.handicapper.profile.AnalysisProfile;

import java.util.List;

import static com.beerandjesus.sportofkings.handicapper.profile.AnalysisProfile.Type.*;
import static com.beerandjesus.sportofkings.handicapper.profile.AnalysisProfileBuilder.analysisProfile;

/**
 * This profile attempts to identify horses matching the following scenario:
 * <p/>
 * - Won last race
 * - Dropping in class to a claiming race
 * - m/l odds 2-1 or less + prime power beats competition
 * - m/l odds 2-1 or greater + prime power within 5 of competition
 * <p/>
 * Such horses are often heavily bet favorites that are vulnerable to upset
 * and other contenders should be considered carefully.
 */
public class VulnerableClaimerProfileResolver implements AnalysisProfileResolver {

    private static final String FIRST_FINISH_POSITION = "1";
    private static final Double TWO = 2.0d;
    private static final Double FIVE = 5.0d;

    // Allow the runner to match competition within 2 Prime Power points
    private static final Double PRIME_POWER_OFFSET = 2d;

    public AnalysisProfile resolve(HorseRace race, Horse horse) {
        // Must have won last race
        List<PastPerformance> pastPerformances = horse.getPastPerformances();
        if (pastPerformances == null || pastPerformances.size() == 0) {
            return null;
        }
        PastPerformance lastRace = pastPerformances.get(0);
        if (!FIRST_FINISH_POSITION.equals(lastRace.getFinishPosition())) {
            return null;
        }
        // Must be a drop in class to a claiming race
        Race r = race.getRace();
        int claimingPrice = 0;
        int lastRaceClaimingPrice = 0;
        try {
            claimingPrice = Integer.valueOf(r.getClaimingPrice());
            lastRaceClaimingPrice = Integer.valueOf(lastRace.getClaimingPrice());
        } catch (Exception e) {
            // Ignore, just use zeros
        }
        if (!r.getType().isCramerClassDrop(claimingPrice, lastRace.getRaceType(), lastRaceClaimingPrice)
                || !r.getType().isClaiming()) {
            return null;
        }
        // Morning line 2/1 or lower must have prime power that exceeds competition
        // Morning line > 2/1 must have prime power within 5 of competition
        Double morningLine = toDouble(horse.getMorningLineOdds());
        Double primePower = toDouble(horse.getPrimePowerRating());
        if (morningLine == null || primePower == null) {
            return null;
        }
        if (morningLine > TWO) {
            primePower += FIVE;
        }
        if (adjustedPrimePowerExceedsCompetition(primePower, race.getHorses())) {
            return analysisProfile(VULNERABLE_CLAIMER, 1);
        }
        return null;
    }

    private Double toDouble(String number) {
        try {
            return Double.valueOf(number);
        } catch (Exception e) {
            return null;
        }
    }
    private boolean adjustedPrimePowerExceedsCompetition(Double primePower, List<Horse> horses) {
        for (Horse h : horses) {
            Double otherPrimePower = toDouble(h.getPrimePowerRating());
            if (otherPrimePower == null) {
                return false;
            }
            if (otherPrimePower > primePower) {
                return false;
            }
        }
        return true;
    }
}
